home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DTOSHI2.ZIP / mpgfx / source / gfxanim.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-18  |  10.0 KB  |  407 lines

  1.  
  2. // gfxanim.cpp
  3. //
  4. // Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.
  5.  
  6. #include "stdgfx.h"
  7. #include "gfxanim.h"
  8. #include "gfxfiles.h"
  9.  
  10. ANIMIMAGE::ANIMIMAGE () : IMAGE ( IMAGE_TOPDOWN )
  11.   {
  12.     NumFrames = 0;
  13.     Frames = NULL;
  14.     BaseImage = NULL;
  15.   } // End of Constructor for ANIMIMAGE
  16.  
  17. ANIMIMAGE::~ANIMIMAGE ()
  18.   {
  19.     Destroy ();
  20.   } // End of Destructor for ANIMIMAGE
  21.  
  22. BOOLEAN ANIMIMAGE::CreateFrames ( LONG Num )
  23.   {
  24.     DestroyFrames ();
  25.     Frames = new ANIMFRAME [Num];
  26.     if (Frames==NULL)
  27.       return FAILURE;
  28.       
  29.     NumFrames = Num;
  30.     
  31.     LONG i;
  32.     for (i=0;i<NumFrames;i++)  
  33.       {
  34.         Frames[i].NumChunks = 0;
  35.         Frames[i].Size = 0;
  36.         Frames[i].Chunks = NULL;
  37.       } // End for
  38.     return SUCCESS;
  39.   } // End of CreateFrames for ANIMIMAGE
  40.  
  41. VOID ANIMIMAGE::DestroyFrame ( ANIMFRAME *Frame )
  42.   {
  43.     if (Frame->Chunks!=NULL)
  44.       {
  45.         delete Frame->Chunks;  
  46.       } // End if  
  47.     Frame->Chunks = NULL;
  48.   } // End of DestroyFrame for ANIMIMAGE
  49.   
  50. VOID ANIMIMAGE::DestroyFrames ()
  51.   {
  52.     if (Frames!=NULL)
  53.       {
  54.         LONG i;
  55.         for (i=0;i<NumFrames;i++)
  56.           {
  57.             DestroyFrame ( &(Frames[i]) );
  58.           } // End for
  59.         delete Frames;  
  60.       } // End if
  61.          Frames = NULL;
  62.   } // End of DestroyFrames for ANIMIMAGE
  63.  
  64. VOID ANIMIMAGE::Destroy ()
  65.   {
  66.     IMAGE::Destroy ();
  67.     DestroyBaseImage ();    
  68.     DestroyFrames ();
  69.   } // End of Destroy for ANIMIMAGE
  70.  
  71. BOOLEAN ANIMIMAGE::CreateBaseImage ()
  72.   {
  73.     LONG Size;
  74.     Size = BytesPerRow*Height;
  75.     if (Size<=0)
  76.       return FAILURE;
  77.       
  78.     BaseImage = new BYTE [(LONG)Size];
  79.     if (BaseImage==NULL)
  80.       return FAILURE;
  81.     memset ( BaseImage, 0, Size );
  82.     return SUCCESS;  
  83.   } // End of CreateBaseImage for ANIMIMAGE
  84.  
  85. VOID ANIMIMAGE::DestroyBaseImage ()
  86.   {
  87.     if (BaseImage!=NULL)
  88.       delete BaseImage;
  89.     BaseImage = NULL;    
  90.   } // End of DestroyBaseImage for ANIMMAGE
  91.  
  92. VOID ANIMIMAGE::SetBaseImage ( IMAGE *Image, LONG Sx, LONG Sy )
  93.   {
  94.     if (BaseImage==NULL)
  95.       return;
  96.  
  97.     LONG i;
  98.     BYTE *SrcBuffer;
  99.  
  100.     for (i=0;i<Height;i++)
  101.       {
  102.         SetOffset ( 0, i );
  103.         SrcBuffer = Image->SetOffset ( Sx, Sy+i );
  104.         memcpy ( BaseImage+Offset, SrcBuffer, BytesPerRow );
  105.       } // End for    
  106.   } // End of SetBaseImage for ANIMIMAGE
  107.   
  108. VOID ANIMIMAGE::RecordFrame ( LONG FrameNumber, IMAGE *Image, LONG Sx, LONG Sy )
  109.   {
  110.     if ((FrameNumber<0)||(FrameNumber>=NumFrames))
  111.       return;
  112.     if (BaseImage==NULL)
  113.       return;  
  114.  
  115.     if (FrameNumber==0)
  116.       {
  117.         SetBaseImage ( Image, Sx, Sy );  
  118.         return;
  119.       } // End if  
  120.         
  121.     ANIMFRAME *Frame;
  122.     Frame = &(Frames[FrameNumber]);  
  123.     DestroyFrame ( Frame );
  124.         
  125.     BYTE *TempSrcBuffer;
  126.     BYTE *ChunkBuffer;
  127.     BYTE *DataBuffer;
  128.  
  129.     LONG Size;
  130.     Size = BytesPerRow*Height;
  131.  
  132.     TempSrcBuffer = new BYTE [Size];
  133.     DataBuffer = new BYTE [Size*2];
  134.     ChunkBuffer = new BYTE [(LONG)0xFFFF];
  135.  
  136.     // Create TempSrcBuffer
  137.     LONG i;
  138.     LONG Offset;
  139.     Offset = 0;
  140.     for (i=0;i<Height;i++)
  141.       {
  142.         memcpy ( TempSrcBuffer+Offset, Image->SetOffset ( Sx, Sy+i ), BytesPerRow );
  143.         Offset += BytesPerRow;
  144.       } // End for
  145.     
  146.     LONG Count;
  147.     LONG cCount;    // Compressed Count
  148.     LONG SkipCount;
  149.     LONG DumpCount;
  150.     LONG NumChunks;
  151.     BYTE CurPix,SrcPix;    
  152.  
  153.     Count=0;
  154.     CurPix = BaseImage[Count];
  155.     SrcPix = TempSrcBuffer[Count];
  156.     Count++;
  157.  
  158.     cCount = 0;
  159.     NumChunks = 0;
  160.     
  161.     while (Count<Size)
  162.       {
  163.         if (CurPix==SrcPix)
  164.           {
  165.             SkipCount=0;  
  166.             while ((CurPix==SrcPix)&&(Count<Size)&(SkipCount<(LONG)0x7FFF))
  167.               {
  168.                 SkipCount++;  
  169.                 CurPix = BaseImage[Count];
  170.                 SrcPix = TempSrcBuffer[Count];
  171.                 Count++;
  172.               } // End while
  173.             *(SHORT*)(ChunkBuffer+cCount) = (SHORT)(-SkipCount);
  174.             cCount += sizeof(SHORT);
  175.             NumChunks++;
  176.           } // End if
  177.         else
  178.           {
  179.             DumpCount=0;  
  180.             while ((CurPix!=SrcPix)&&(Count<Size)&(DumpCount<(LONG)0x7FFF))
  181.               {
  182.                 DataBuffer[DumpCount++] = SrcPix;
  183.                 CurPix = BaseImage[Count];
  184.                 SrcPix = TempSrcBuffer[Count];
  185.                 Count++;
  186.               } // End while
  187.             *(SHORT*)(ChunkBuffer+cCount) = (SHORT)DumpCount;
  188.             cCount += sizeof(SHORT);
  189.  
  190.             for (i=0;i<DumpCount;i++)
  191.               {
  192.                 *(ChunkBuffer+cCount) = DataBuffer[i];
  193.                 cCount++;
  194.               } // End for  
  195.               
  196.             NumChunks++;
  197.           } // End else    
  198.       } // End while
  199.  
  200.     // Check if it is worth compressing
  201.     if (cCount>Size)
  202.       {
  203.         Frame->NumChunks = -1;
  204.         Frame->Size = Size;
  205.         Frame->Chunks = new BYTE [Size];
  206.         memcpy ( Frame->Chunks, TempSrcBuffer, Size );  
  207.       } // End if
  208.     else
  209.       {
  210.         // Copy All Chunks into Chunk Data
  211.         Frame->NumChunks = NumChunks;
  212.         Frame->Size = cCount;
  213.         if (cCount==0)
  214.           Frame->Chunks = NULL;
  215.         else  
  216.           Frame->Chunks = new BYTE [cCount];
  217.         memcpy ( Frame->Chunks, ChunkBuffer, cCount );          
  218.       } // End else  
  219.           
  220.     delete TempSrcBuffer;
  221.     delete ChunkBuffer;    
  222.     delete DataBuffer;    
  223.   } // End of RecordFrame for ANIMIMAGE
  224.  
  225. VOID ANIMIMAGE::SetFrame ( LONG FrameNumber )
  226.   {
  227.     if (BaseImage==NULL)
  228.       return;
  229.     if (Buffer==NULL)
  230.       return;
  231.     if ((FrameNumber<0)||(FrameNumber>=NumFrames))
  232.       return;
  233.     
  234.     LONG Size;
  235.     Size = BytesPerRow*Height;      
  236.     // First, copy base image into buffer
  237.     memcpy ( Buffer, BaseImage, Size );
  238.  
  239.     if (FrameNumber==0)
  240.       return;
  241.        
  242.     LONG i;
  243.     LONG RepCount;
  244.     BYTE* ChunkBuffer;
  245.     BYTE* DestBuffer;
  246.     ANIMFRAME *Frame;
  247.     Frame = &(Frames[FrameNumber]);
  248.     ChunkBuffer = Frame->Chunks;
  249.  
  250.     if (ChunkBuffer==NULL)
  251.       return;
  252.       
  253.     DestBuffer = Buffer;
  254.     
  255.     // Copy Delta Compressed Data
  256.     for (i=0;i<Frame->NumChunks;i++)
  257.       {
  258.         RepCount = *((SHORT*)ChunkBuffer);
  259.         ChunkBuffer += sizeof(SHORT);
  260.         if (RepCount<0)
  261.           DestBuffer += -RepCount;
  262.         else
  263.           {
  264.             memcpy ( DestBuffer, ChunkBuffer, RepCount );
  265.             ChunkBuffer += RepCount;
  266.             DestBuffer += RepCount;
  267.           } // End else  
  268.       } // End for
  269.   } // End of SetFranme for ANIMIMAGE
  270.  
  271. BOOLEAN ANIMIMAGE::Save ( STRING FileName )
  272.   {
  273.     FILEHANDLE f;
  274.  
  275.     if (BaseImage==NULL)
  276.       return FAILURE;
  277.       
  278.     f = File.Open ( FileName, OPEN_BINARY | OPEN_WRITE );
  279.     if (f==NULL)
  280.       return FAILURE;
  281.  
  282.     CHAR Str[32];
  283.     sprintf ( Str, "ANIMATION" );
  284.     File.Write ( f, Str, 32 );
  285.  
  286.     LONG Wd,Ht,BytesPerPix,NumFrm;
  287.     Wd = Width;
  288.     Ht = Height;
  289.     BytesPerPix = BytesPerPixel;
  290.     NumFrm = NumFrames;
  291.  
  292.     #if defined (__MSBFIRST__)
  293.       SwapDWord ( (DWORD*)&Wd );
  294.       SwapDWord ( (DWORD*)&Ht );
  295.       SwapDWord ( (DWORD*)&BytesPerPix );
  296.       SwapDWord ( (DWORD*)&NumFrm );
  297.     #endif
  298.     
  299.     File.Write ( f, &Wd, sizeof(LONG) );     
  300.     File.Write ( f, &Ht, sizeof(LONG) );     
  301.     File.Write ( f, &BytesPerPix, sizeof(LONG) );     
  302.     File.Write ( f, &NumFrm, sizeof(LONG) );
  303.  
  304.     LONG Size;
  305.     Size = BytesPerRow*Height;
  306.  
  307.     File.Write ( f, BaseImage, Size );
  308.  
  309.     INT i;
  310.     LONG NumChunks,ChunkSize;
  311.     for (i=1;i<NumFrames;i++)
  312.       {
  313.         NumChunks = Frames[i].NumChunks;  
  314.         ChunkSize = Frames[i].Size;
  315.         #if defined (__MSBFIRST__)
  316.           SwapDWord ( (DWORD*)&NumChunks );
  317.           SwapDWord ( (DWORD*)&Size );
  318.         #endif
  319.         File.Write ( f, &NumChunks, sizeof(LONG) );
  320.         File.Write ( f, &Size, sizeof(LONG) );
  321.         File.Write ( f, Frames[i].Chunks, Frames[i].Size );
  322.       } // End for
  323.       
  324.     File.Close ( f );
  325.     return SUCCESS;    
  326.   } // End of Save for ANIMIMAGE
  327.  
  328. BOOLEAN ANIMIMAGE::Load ( STRING FileName )
  329.   {
  330.     FILEHANDLE f;
  331.  
  332.     f = File.Open ( FileName, OPEN_BINARY | OPEN_READ );
  333.     if (f==NULL)
  334.       return FAILURE;
  335.  
  336.     Destroy ();
  337.     DestroyFrames ();
  338.     
  339.     CHAR Str[32];
  340.     File.Read ( f, Str, 32 );
  341.     if(strcmp ( Str, "ANIMATION" ))
  342.       {
  343.         File.Close ( f );
  344.         return FAILURE;  
  345.       } // End if
  346.       
  347.     File.Read ( f, &Width, sizeof(LONG) );     
  348.     File.Read ( f, &Height, sizeof(LONG) );     
  349.     File.Read ( f, &BytesPerPixel, sizeof(LONG) );
  350.  
  351.     #if defined (__MSBFIRST__)
  352.       SwapDWord ( (DWORD*)&Width );
  353.       SwapDWord ( (DWORD*)&Height );
  354.       SwapDWord ( (DWORD*)&BytesPerPixel );
  355.     #endif
  356.     
  357.     LONG NewFormat=0;
  358.     switch (BytesPerPixel)
  359.       {
  360.         case 1 :
  361.           NewFormat = IMAGE_8BIT;
  362.           break; 
  363.         case 2 :
  364.           NewFormat = IMAGE_16BIT;
  365.           break; 
  366.         case 3 :
  367.           NewFormat = IMAGE_24BIT;
  368.           break; 
  369.       } // End switch
  370.  
  371.     if (Create ( NewFormat, Width, Height )==FAILURE)
  372.       return FAILURE;
  373.  
  374.     if (CreateBaseImage()==FAILURE)
  375.       return FAILURE;
  376.       
  377.     File.Read ( f, &NumFrames, sizeof(LONG) );
  378.     
  379.     #if defined (__MSBFIRST__)
  380.       SwapDWord ( (DWORD*)&NumFrames );
  381.     #endif
  382.  
  383.     if (CreateFrames ( NumFrames )==FAILURE)
  384.       return FAILURE;
  385.     
  386.     LONG Size;
  387.     Size = BytesPerRow*Height;
  388.  
  389.     File.Read ( f, BaseImage, Size );
  390.  
  391.     INT i;
  392.     for (i=1;i<NumFrames;i++)
  393.       {
  394.         File.Read ( f, &(Frames[i].NumChunks), sizeof(LONG) );
  395.         File.Read ( f, &(Frames[i].Size), sizeof(LONG) );
  396.         #if defined (__MSBFIRST__)
  397.           SwapDWord ( (DWORD*)&(Frames[i].NumChunks) );
  398.           SwapDWord ( (DWORD*)&(Frames[i].Size) );
  399.         #endif
  400.         File.Read ( f, Frames[i].Chunks, Frames[i].Size );
  401.       } // End for
  402.       
  403.     File.Close ( f );
  404.     return SUCCESS;    
  405.   } // End of Load for ANIMIMAGE
  406.  
  407.